from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth, MultiAuth
from werkzeug import security
from itsdangerous import TimedJSONWebSignatureSerializer

#--------------------#
class AuthMgrBase(object):
    def generate_password_hash(self, pwd):
        return security.generate_password_hash(pwd)
    def check_password_hash(self, hash_pwd, pwd):
        return security.check_password_hash(hash_pwd, pwd)
    def _set_token_data(self, jwt, data, tp):
        return jwt.dumps({ 'data': data, 'type': tp })
    def _get_token_data(self, jwt, token, tp):
        try:
            data = jwt.loads(token)
        except:
            return None
        #
        if data is None:
            return None
        if ('type' not in data):
            return None
        if (data['type'] != tp):
            return None
        if ('data' not in data):
            return None
        return data['data']
#--------------------#
class SimpleAuthMgr(AuthMgrBase):
    def __init__(self, secret_key, expires_in=600,
            basic_scheme='Basic', basic_realm=None,
            token_scheme='Bearer', token_realm=None):
        self.basic = HTTPBasicAuth(scheme=basic_scheme, realm=basic_realm)
        self.token = HTTPTokenAuth(scheme=token_scheme, realm=token_realm)
        self.multi = MultiAuth(self.basic, self.token)
        self.jwt = TimedJSONWebSignatureSerializer(secret_key, expires_in=expires_in)
    def generate_token(self, data):
        return self._set_token_data(self.jwt, data, 'token')
    def token_data(self, token):
        return self._get_token_data(self.jwt, token, 'token')
#--------------------#
class AuthMgr(AuthMgrBase):
    def __init__(self, secret_key, basic_scheme='Basic', basic_realm=None,
            atoken_scheme='Bearer', atoken_realm=None, aexpires_in=600,
            rftoken_scheme='Bearer', rftoken_realm=None, rfexpires_in=3600*24 ):
        self.basic = HTTPBasicAuth(scheme=basic_scheme, realm=basic_realm)
        #
        self.atoken = HTTPTokenAuth(scheme=atoken_scheme, realm=atoken_realm)
        self.amulti = MultiAuth(self.basic, self.atoken)
        self.ajwt = TimedJSONWebSignatureSerializer(secret_key, expires_in=aexpires_in)
        #
        self.rftoken = HTTPTokenAuth(scheme=rftoken_scheme, realm=rftoken_realm)
        self.rfmulti = MultiAuth(self.basic, self.rftoken)
        self.rfjwt = TimedJSONWebSignatureSerializer(secret_key, expires_in=rfexpires_in)
    def generate_atoken(self, data):
        return self._set_token_data(self.ajwt, data, 'access_token')
    def atoken_data(self, token):
        return self._get_token_data(self.ajwt, token, 'access_token')
    def generate_rftoken(self, data):
        return self._set_token_data(self.rfjwt, data, 'refresh_token')
    def rftoken_data(self, token):
        return self._get_token_data(self.rfjwt, token, 'refresh_token')
#--------------------#